﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

namespace TinyGet.Helpers
{
    public class Base36
    {
        private static char[] base36Chars;

        /// <summary>
        /// initilises the characters in base 36
        /// </summary>
        protected static void InitilizeBase36()
        {
            base36Chars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
        }

        /// <summary>
        /// Encodes an int into a base 36 string
        /// if you were to alter the values in the b36cd then 
        /// this could be to any base value.
        /// </summary>
        /// <param name="value">The input decimal value.</param>
        /// <returns>The output string base 36 converter.</returns>
        public static string Encode(Int64 value)
        {
            InitilizeBase36();   // set the char[] array
            string returnValue = ""; // starting value
            while (value != 0)
            {
                returnValue = base36Chars[value % base36Chars.Length] + returnValue;
                value /= base36Chars.Length;
            }
            returnValue = returnValue.ToUpper();
            return returnValue;
        }

        /// <summary>
        /// This decodes the base 36 number into a decimal number
        /// though this could be used to decode any base number depending on the input
        /// on the char[] base36Chars.
        /// </summary>
        /// <param name="input">The input string.</param>
        /// <returns>The decimal value of the base 36 number.</returns>
        public static Int64 Decode(string input)
        {
            InitilizeBase36();
            input = input.Trim();
            input = input.ToLower();
            Int64 returnValue = 0;

            char[] characters = input.ToCharArray();
            Array.Reverse(characters);

            for (int i = 0; i < characters.Length; i++)
            {
                // find the index in the array that the char resides
                int valueindex = Array.IndexOf(base36Chars, characters[i]);
                // the actual value given by that is 
                // the index multiplied by the base number to the power of the index
                double temp = valueindex * Math.Pow(base36Chars.Length, i);
                // add this value to the counter until there are no more values
                returnValue += Convert.ToInt64(temp);
            }
            // return the total result
            return returnValue;
        }
    }

}
